using System;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using WCS.Infrastructure.EFCore;
using WCS.Repository.Interface;

namespace WCS.Repository.Instance
{
    public sealed class EfCoreUnitOfWork : IUnitOfWork
    {
        private readonly wcsDbContext _db;
        private IDbContextTransaction? _tx;

        public EfCoreUnitOfWork(wcsDbContext db)
        {
            _db = db;
        }

        public async Task<IDbContextTransaction> BeginTransactionAsync(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted, CancellationToken cancellationToken = default)
        {
            if (_tx != null)
                throw new InvalidOperationException("Transaction already started.");
            _tx = await _db.Database.BeginTransactionAsync(isolationLevel, cancellationToken);
            return _tx;
        }

        public Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
            => _db.SaveChangesAsync(cancellationToken);

        public async Task CommitAsync(CancellationToken cancellationToken = default)
        {
            if (_tx == null) return;
            // 二次保障：即使外部忘记 SaveChanges，这里也做最终一次 flush（不会重复写入，最多返回 0）
            await _db.SaveChangesAsync(cancellationToken);
            await _tx.CommitAsync(cancellationToken);
            await _tx.DisposeAsync();
            _tx = null;
        }

        public async Task RollbackAsync(CancellationToken cancellationToken = default)
        {
            if (_tx == null) return;
            await _tx.RollbackAsync(cancellationToken);
            await _tx.DisposeAsync();
            _tx = null;
        }

        public async ValueTask DisposeAsync()
        {
            if (_tx != null)
            {
                await _tx.DisposeAsync();
                _tx = null;
            }
        }
    }
}